#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

#include <ptrace.h>
#include <process.h>
#include <stdio.h>
#include <console.h>
#include <clock.h>


/**
 * cause current process starting tracing its childs
 * @param pid the pid of the child
 */
void
um_ptrace (int pid) 
{
	int status;
	siginfo_t siginfo;
	int running = 1;

	while (running) {
		wait (&status);
		if (WIFEXITED (status) || WIFSIGNALED (status))
			break;
		ptrace (PTRACE_GETSIGINFO, pid, 0, &siginfo);
		switch (siginfo.si_signo) {
		case SIGVTALRM:
		case SIGIO:
			ptrace (PTRACE_CONT, pid, 0, siginfo.si_signo);
			break;
		case SIGUSR1:
			running = 0;
			break;
		default:
			;
			//ptrace (PTRACE_KILL, pid, 0, 0);
		}
	}
}


/**
 * Resume anything we have changed.
 */
void
child_terminal ()
{
	cons_dtor ();
}

/**
 * Handling SIGIO and exit if SPACE is typed.
 */
void
child_sigio (int dummy)
{
	int c = cons_getc ();
	cprintf ("[%d] %c\n", c, (char)c);
	if (c == 32) {
		//child_terminal ();
		raise (SIGUSR1);  /* Inform the tracing thread that all are done. */
		_exit (0);
	}
}


/**
 * entry of the traced children
 */
void
ptraced_child (void) 
{
	signal (SIGIO, child_sigio);

	int pid = um_getpid ();
	
	cprintf ("Child's pid: %d\n", pid);
	if (ptrace (PTRACE_TRACEME, 0, NULL, NULL) < 0)
		goto fail;
	
	while (1);

fail:
	kill (pid, SIGKILL);
}
